#!/bin/bash

# 帮助
helping(){
    cd $fileDir
    . README.md
    if [ ! "$1" == "" ] && [[ $helpList =~ $1 ]]; then
        eval echo -e \$${1}Help
    else
        echo -e $helpHelp
    fi
}

# 打印
log(){ #打印并记录
    color=$1
    shift
    echo -e "\033[${color}$@ \033[0m"
    echo -e "\033[${color}$@ \033[0m" >> $fileDir/record/log/$logFileMul
    echo -e "$@" >> $fileDir/record/log/$logFile
}
error()   { log 31m $@ ; } # 红色错误
warning() { log 33m $@ ; } # 黄色告警
success() { log 32m $@ ; } # 绿色成功
hint()    { log 37m $@ ; } # 白色提示
title()   { log 34m '---->'$@ ; } # 蓝色标题
logV(){ #打印版本信息
    echo -e "\033[35m$@ \033[0m"
    echo $@ >> ../record/version.info
}

# 更新Dockerfile部分独立出来
renew(){
    cd $fileDir
    mkdir -p makeImage
    cd makeImage
    for i in $imageList; do
        mkdir -p $i
        cp -r ../config/imageFile/${i}/* ../makeImage/$i
        fileTarget="../makeImage/$i/Dockerfile"
        if [ "$aptOri" != "" ]; then
            sed -i "s?#<aptOri>??g" $fileTarget
            sed -i "s?aptValue?$aptOri?g" $fileTarget
        fi
        sed -i "s?proxyValue?$proxy?g" $fileTarget
        sed -i "s?pipValue?$pipOri?g" $fileTarget
    done
}

# 预处理，转移文件
pre(){
    title "The preprocessing operation will process the following images"
    title "(预处理操作将会处理以下镜像):"
    hint $imageList
    renew
    cd $fileDir
    cd sourceFile
    . fileList.sh
    newImageList=""
    for i in $imageList; do
        title "$i image file copy($i镜像文件复制)"
        canDo="yes"
        imageFile=$(eval echo \$${i}File)
        for j in $imageFile; do
            hint "copy $j to $i (复制$j文件至$i)"
            if [ ! -f $j  ]; then
                warning "$j does not exist, the $i image cannot be built, the image will be skipped"
                warning "$j不存在，无法构建$i镜像，该镜像将被跳过"
                canDo="no"
                break
            else
                cp $j ../makeImage/$i/
            fi
        done
        if [ "$canDo" == "yes" ]; then
            newImageList=$newImageList' '$i
        fi
    done
    cd ..
    if [[ ! $(find ./makeImage/* -name *.run) == "" ]]; then chmod +x ./makeImage/*/*.run; fi
    imageList=$newImageList

##-------->不同镜像的特定操作
    # train镜像的特定处理步骤
    if [[ $imageList =~ "train" ]]; then
        title "Train image file processing(训练镜像文件处理)"
        cd makeImage/train
        cp /etc/ascend_install.info ascend_install.info
        cp /usr/local/Ascend/driver/version.info version.info
        hint "Unzip the toolkit package(解压toolkit包)"
        ./Ascend-cann-toolkit_*_linux-${archType}.run --noexec --extract=toolkit
        hint "unzip complete(解压完毕)"
        cd ../..
    fi
    # mindinsight镜像的特定处理步骤
    if [[ $imageList =~ "mindinsight" ]]; then
        title "mindinsight image file processing(可视化镜像文件处理)"
        cd makeImage/mindinsight
        chmod +x start.sh
        dos2unix start.sh
        cd ../..
    fi
    # access镜像的特定处理步骤
    if [[ $imageList =~ "access" ]]; then
        title "Access image file processing(access镜像文件处理)"
        cd makeImage/access
        hint "Unzip the access package(解压access包)"
        unzip -n Ascend-mindxdl-access-manager_*_linux-${archType}.zip
        hint "unzip complete(解压完毕)"
        cd ../..
    fi
    # license镜像的特定处理步骤
    if [[ $imageList =~ "license" ]]; then
        title "License image file processing(license镜像文件处理)"
        cd ./makeImage/license
        hint "Unzip the license package(解压license包)"
        unzip -n Ascend-mindxdl-license-manager_*_linux-${archType}.zip
        hint "unzip complete(解压完毕)"
        cd ../..
    fi
    # modelarts镜像的特定处理步骤
    if [[ $imageList =~ "modelarts" ]]; then
        title "Modelarts image file processing(上云镜像文件处理)"
        cd ./makeImage/modelarts
        hint "Unzip the toolkit package(解压toolkit包)"
        ./Ascend-cann-toolkit_*_linux-${archType}.run --noexec --extract=toolkit
        hint "unzip complete(解压完毕)"
        cd ../..
    fi
    success "After the preprocessing is complete, the subsequent processing image list is as follows:"
    success "(预处理完毕，后续处理镜像列表如下):"
    hint $imageList
}

check(){
    cd $fileDir/makeImage
    logV "====>time(时间):"$(date)
    newImageList=""
    title "Version number check and acquisition(版本号检查与获取)"
    if [ -f "imageVersion.list" ]; then 
        . imageVersion.list
        rm -f imageVersion.list
    fi
    for i in $imageList; do
        title "Get the $i version number(获取$i版本号)"
        logV "---->$i file version number($i文件版本号)"
        case $i in
            infer | infer_3c | infer_sem)
                nnrt=$(./$i/Ascend-cann-nnrt_*.run --version|grep NNRT)
                echo ""
                logV $nnrt
                mxmanufacture=$(./$i/Ascend-mindxsdk-mxmanufacture_*.run --version|grep 'mxManufacture version')
                echo ""
                logV $mxmanufacture
                inferV1=${mxmanufacture#*version:}
                mxserving=$(./$i/Ascend-mindxsdk-mxserving*.run --version|grep 'mxserving version')
                echo ""
                logV $mxserving
                inferV2=${mxserving#*version:}
                if [ $inferV1 != $inferV2 ]; then
                    error "mxManufacture and mxserving versions are inconsistent, $i imageing will be skipped"
                    error "(mxManufacture与mxserving版本不一致，$i镜像将被跳过)"
                    imageList=${imageList/" $i"/""}
                else
                    eval ${i}Version=$inferV1
                    hint "SDK version is $inferV1"
                    hint "SDK版本号为：$inferV1"
                fi
                ;;
            train)
                nnae=$(./train/Ascend-cann-nnae_*.run --version|grep "NNAE\ ")
                echo ""
                logV $nnae
                trainV1=${nnae#* }
                toolkit=$(./train/Ascend-cann-toolkit_*.run --version|grep "Toolkit\ ")
                echo ""
                logV $toolkit
                trainV2=${toolkit#* }
                if [ $trainV1 != $trainV2 ]; then
                    error "NNAE and Toolkit version are inconsistent, train imageing will be skipped"
                    error "(NNAE与Toolkit版本不一致，train镜像将被跳过)"
                    imageList=${imageList/" train"/""}
                else
                    trainVersion=$trainV1
                    hint "CANN version is $trainVersion"
                    hint "CANN版本号为：$trainVersion"
                fi
                mindsporeFile=$(ls train | grep mindspore)
                mindspore=${mindsporeFile#mindspore_ascend-}
                mindspore="mindspore "${mindspore%-cp37-cp37m-linux*}
                logV $mindspore
                ;;
            mindinsight)
                mindinsightFile=$(ls mindinsight|grep mindinsight)
                mindinsight=${mindinsightFile#mindinsight-}
                mindinsightVersion=${mindinsight%-py3*}
                logV "mindinsight "$mindinsightVersion
                ;;
            modelarts)
                modelarts=$(./modelarts/Ascend-cann-toolkit_*.run --version|grep Toolkit)
                echo ""
                logV $modelarts
                modelartsVersion=${modelarts#* }
                ;;
            access)
                accessFile=$(ls access|grep yaml)
                access=${accessFile#access-manager-}
                accessVersion=${access%.yaml}
                logV "access "$accessVersion
                ;;            
            license)
                licenseFile="$(ls license|grep .yaml)"
                if [ ${#licenseFile} -gt 0 ] && [ -e "license/${licenseFile}" ]; then
                  license=${licenseFile#license-manager-}
                  licenseVersion=${license%.yaml}
                  logV "license "$licenseVersion
                else
                  licenseFile=$(ls license|grep Ascend-mindxdl-license-manager)
                  license=${licenseFile#Ascend-mindxdl-license-manager_}
                  licenseVersion="v"${license%%_*}
                  logV "license "$licenseVersion
                fi
                ;;
        esac
    done
    echo "##The image version list is as follows(镜像版本列表如下):" >> imageVersion.list
    for i in $allImage; do
        echo "${i}Version="$(eval echo \$${i}Version) >> imageVersion.list
    done
    success "After the checking is complete, the subsequent processing image list is as follows:"
    success "(检查完毕，后续处理镜像列表如下):"
    hint $imageList
    cd ..
}

saving(){
    mkdir -p imageBag
    needSave="yes"
    if [[ ! $actionList =~ "--build" ]]; then build; fi
}

# 生成镜像
build(){
    cd $fileDir
    if [[ "$imageList" =~ "infer" ]]; then cd sourceFile && docker load -i hello-world.tar && cd ..; fi
    mkdir -p imageBag
    cd makeImage
    if [ ! -f imageVersion.list ]; then
        error "imageVersion.list does not exist, please use --check to generate the image version number"
        error "Or manually edit ./makeImage/imageVersion.list to customize the version number"
        error "(imageVersion.list不存在，请使用--check生成镜像版本号"
        error "或者手动编辑./makeImage/imageVersion.list自定义版本号)"
    else
        chmod u+x imageVersion.list && . imageVersion.list
    fi
    if [ -f imageName.list ]; then chmod u+x imageName.list && . imageName.list && rm -f imageName.list; fi
    isError=false
    newImageList=""
    for i in $imageList; do
        cd $i
        title "Start to build the $i image(开始构建$i镜像)"
        imageVersion=$(eval echo \$${i}Version)
        if [[ "$imageVersion" == "" ]]; then 
            error "imageVersion.list does not exist, please use --check to generate the image version number"
            error "Or manually edit ./makeImage/imageVersion.list to customize the version number"
            error "The image build will be skipped"
            error "($i镜像版本号不存在，请使用./run --check生成镜像版本号"
            error "或者手动编辑./makeImage/imageVersion.list自定义版本号"
            error "该镜像构建将被跳过)"
            continue
        fi
        imageName="ascend-"$i:$(eval echo \$${i}Version)-$archType
        # 推理镜像生成同名hello-world镜像可以用于网页上传
        if [[ "$i" =~ "infer" ]];then
            docker tag hello-world $imageName
            docker save -o ../../imageBag/hello-$i.tar $imageName
            docker image rm $imageName
        fi
        docker build -t $imageName .
        imageId=$(docker images -q $imageName)
        if [[ "$imageId" == "" ]]; then 
            error "$i image build failed, please locate the problem according to the image build log"
            error "($i镜像构建失败，请根据镜像构建日志定位问题)"
            isError=false
            continue
        fi
        title "Build completed(构建完成)"
        success "The $i image is built, the image name is $imageName, and the image id is $imageId"
        success "$i镜像构建完成，镜像名为$imageName，镜像id为$imageId"
        eval ${i}Name=$imageName
        eval ${i}Id=$imageId
        newImageList=$newImageList" $i"
        if [[ $needSave == "yes" ]]; then
            hint "Saving(正在保存)..."
            imageBag=${i}-$(eval echo \$${i}Version)-$archType.tar
            docker save -o ../../imageBag/$imageBag $imageName
            success "After saving, the saved package is named $imageBag"
            success "保存完成，保存包名为$imageBag"
            eval ${i}Bag=$imageBag
        fi
        cd ..
    done
    for i in $newImageList; do
        if [[ ! $pushList =~ $i && $canPush =~ $i ]]; then pushList="$pushList $i"; fi
    done
    echo 'pushList="'$pushList'"' >> imageName.list
    for i in $allImage; do
        echo ""                                      >> imageName.list
        echo "${i}Name=\""$(eval echo \$${i}Name)'"' >> imageName.list
        echo "${i}Id=\""$(eval echo \$${i}Id)'"'     >> imageName.list
        echo "${i}Bag=\""$(eval echo \$${i}Bag)'"'   >> imageName.list
    done
    cd ..
    cp makeImage/imageName.list imageBag/
    chmod +x imageBag/imageName.list
    if [[ $isError == "True" ]]; then warning $errorHelp ; fi
}

## 清理文件1-删除中间文件
clear1(){
    if [ -d $fileDir/makeImage ]; then
        cd $fileDir/makeImage
        for i in $allImage; do
            if [ ! -d $i ]; then continue; fi
            cd $i
            allFile=$(ls)
            for j in $allFile; do
                if [[ ! $saveFile =~ $j ]];then rm -rf $j; fi
            done
            cd $fileDir/makeImage
        done
    fi
}

#清理文件2-删除中间文件及镜像包
clear2(){
    clear1
    cd $fileDir/imageBag
    rm -f ./*.tar
}

#清理文件3-删除所有大文件
clear3(){
    clear2
    cd $fileDir/sourceFile
    rm -f ./*.zip ./*.run ./*.whl
}

#清理文件4-删除所有记录文件
clear4(){
    clear3
    cd $fileDir
    rm -rf ./imageBag/*
    rm -rf ./makeImage/*
    rm -rf ./record/*
}

##---------------------------------------------->流程开始

# 读取命令
fileDir=$(cd $(dirname $0) && pwd)
cd $fileDir
imageList=""
actionList=""

while [ "$1" != "" ]; do
    case "$1" in
        infer | infer_3c | infer_sem | train | mindinsight | modelarts | access | license )
            imageList=$imageList' '$1
            ;;
        --pre | --renew | --check | --build | --saving | --test | --push | --clear*)
            actionList=$actionList' '$1
            ;;
        --help )
            helping $2
            exit
            ;;
        * )
            helping
            exit
            ;;
    esac
    shift
done

# 配置参数
. ./config/cfg.sh
if [ "$imageList" == "" ] ; then imageList=$presetImage ; fi
if [ "$actionList" == "" ] ; then actionList=$presetAction ; fi
archType=$(arch)
mkdir -p record
mkdir -p record/log
recordTime=$(date "+%Y-%m-%d_%H%M%S")
logFile="${recordTime}-running.log"
logFileMul="${recordTime}-runningMul.log"
ln -snf ./log/$logFile ./record/running.log
ln -snf ./log/$logFileMul ./record/runningMul.log

# 执行命令
for i in $allAction; do
    if [[ $actionList =~ $i ]]; then
        ${i:2}
    fi
done

# 打印日志
echo "================================ALL LOGS==================================="
cd $fileDir
if [ -f ./record/runningMul.log ]; then
    cat ./record/runningMul.log
fi
echo "=================================ENDING===================================="

##---------------------------------------------->流程结束

